package uy.org.softtech.cssuite.core;

import static org.springframework.util.Assert.notNull;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.context.MessageSource;
import org.springframework.validation.BindingResult;

/**
 * Clase abstracta para llevar a cabo las funcionalidades de los formularios. También actúa 
 * como disparador de la transaccionabilidad de la funcionalidad usando Spring AOP.
 * 
 * @author fabian.lobo
 */
public abstract class Comando {
	
	protected final String SERVICIO = getClass().getName() + "#ejecutar";
	
	@Resource(name = "fuente-mensajes")
	private MessageSource fuenteMensajes;
	
	/**
	 * Método para verificar que todos los parámetros han sido seteados correctamente.
	 * 
	 * @author fabian.lobo
	 */
	@PostConstruct
	public void inicializacion(){
		notNull(fuenteMensajes(), "La propiedad [fuenteMensajes] de [" + getClass().getName() + "] no ha sido establecida.");
		
	}
	
	/*
	 * 	METODOS
	 */
	/**
	 * Valida los datos ingresados en el formulario, usando como representación una instancia
	 * de una clase que hereda de {@link Modelo modelo}. Si la validación es exitosa, se ejecuta
	 * la acción.
	 *
	 * @param modelo - Instancia que contiene los datos ingresados en el formulario
	 * @param errores - Lista de errores
	 * @return true si la validación ha sido exitosa (no hay errores de validación) y se pudo ejecutar la acción sin errores
	 * @author fabian.lobo
	 */
	public boolean ejecutar(Modelo modelo, BindingResult errores) throws Exception {
		validaModelo(modelo, errores);
		if(errores.getErrorCount() == 0) {		
			ejecutarComando(modelo, errores);
		}
		return errores.getErrorCount() == 0;
	}

	/**
	 * Ejecucion final de la acción.
	 * 
	 * @param modelo - Instancia que contiene los datos ingresados en el formulario
	 * @param errores - Lista de errores en donde figurará cualquier error en la ejecución
	 * @author fabian.lobo
	 */
	public abstract void ejecutarComando(Modelo modelo, BindingResult errores);

	/**
	 * Realiza la validación de los datos ingresados.
	 * 
	 * @param modelo - Instancia que contiene los datos ingresados en el formulario
	 * @param errores - Lista de errores de las validaciones
	 */
	public abstract void validaModelo(Modelo modelo, BindingResult errores);
	
	/*
	 *  GETTERS
	 */
	public MessageSource fuenteMensajes() {
		return fuenteMensajes;
	}
}
